package io.adrainty.bolee.insurance.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.IdcardUtil;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import io.adrainty.bolee.framework.commons.basic.EnableEnum;
import io.adrainty.bolee.framework.commons.basic.ResponseCode;
import io.adrainty.bolee.framework.commons.basic.ResultDTO;
import io.adrainty.bolee.framework.commons.exception.AppException;
import io.adrainty.bolee.framework.commons.user.SubjectContentUtil;
import io.adrainty.bolee.framework.commons.utils.JsonUtil;
import io.adrainty.bolee.framework.commons.utils.ResultDTOUtil;
import io.adrainty.bolee.insurance.constants.InsuranceConstant;
import io.adrainty.bolee.insurance.models.aggregate.InsuranceProcessDTO;
import io.adrainty.bolee.insurance.models.aggregate.JsonAttributeDTO;
import io.adrainty.bolee.insurance.models.aggregate.RangJsonAttributeDTO;
import io.adrainty.bolee.insurance.models.aggregate.WarrantyTimeDTO;
import io.adrainty.bolee.insurance.models.entity.*;
import io.adrainty.bolee.insurance.models.request.DoInsuranceDTO;
import io.adrainty.bolee.insurance.models.valobj.CheckRuleEnum;
import io.adrainty.bolee.insurance.models.valobj.CustomerRelationEnum;
import io.adrainty.bolee.insurance.models.valobj.OrderStateEnum;
import io.adrainty.bolee.insurance.repository.IWarrantyRepository;
import io.adrainty.bolee.insurance.service.ICustomerRelationService;
import io.adrainty.bolee.insurance.service.IInsuranceCoefficientService;
import io.adrainty.bolee.insurance.service.IInsuranceService;
import io.adrainty.bolee.security.feign.ICompanyFeign;
import io.adrainty.bolee.security.models.entity.CompanyEntity;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author AdRainty
 * @version V1.0.0
 * @since 2025/8/24 下午11:11
 */
public abstract class AbstractInsuranceHandler implements InsuranceHandler {

    @Resource
    protected IInsuranceService insuranceService;

    @Resource
    protected IInsuranceCoefficientService insuranceCoefficientService;

    @Resource
    protected ICompanyFeign companyFeign;

    @Resource
    protected ICustomerRelationService customerRelationService;

    @Resource
    protected IWarrantyRepository warrantyRepository;

    @Resource
    protected IdentifierGenerator identifierGenerator;

    /**
     * 无效保费
     */
    protected static final String ILLEGAL_PREMIUM = "-1";

    @Override
    public List<WarrantyOrderEntity> createWarrantyOrder(WarrantyEntity warrantyEntity) {
        List<WarrantyOrderEntity> warrantyOrderVOs = new ArrayList<>();
        // 总周期数
        Integer periods = warrantyEntity.getPeriods();
        for (int i = 1; i <= periods; i++) {
            WarrantyOrderEntity warrantyOrderVO = WarrantyOrderEntity.builder()
                    .orderNo(String.valueOf(identifierGenerator.nextId(warrantyOrderVOs)))
                    .warrantyNo(warrantyEntity.getWarrantyNo())
                    .companyNo(warrantyEntity.getCompanyNo())
                    .periods(warrantyEntity.getPeriods())
                    .currentPeriod(i)
                    .premium(warrantyEntity.getPremium())
                    .premiums(warrantyEntity.getPremiums())
                    .periodicUnit(warrantyEntity.getPeriodicUnit())
                    .orderState(OrderStateEnum.WAITING_PAY)
                    .build();
            // 利润分成
            if (i == 1) {
                InsuranceProcessDTO insureProcessVO = JsonUtil.fromJson(warrantyEntity.getInsuranceJson(), InsuranceProcessDTO.class);
                // 有代理人
                if (StringUtils.isNotBlank(warrantyEntity.getAgentId())) {
                    BigDecimal individualAgentRate = insureProcessVO.getInsuranceEntity().getIndividualAgentRate();
                    warrantyOrderVO.setAgentFee(
                            warrantyEntity.getPremium().multiply(individualAgentRate)
                                    .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP)
                    );
                    BigDecimal platformAgentRate = insureProcessVO.getInsuranceEntity().getPlatformAgentRate();
                    warrantyOrderVO.setPlatformFee(
                            warrantyEntity.getPremium().multiply(platformAgentRate)
                                    .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP)
                    );
                    // 无代理人
                } else {
                    warrantyOrderVO.setAgentFee(BigDecimal.ZERO);
                    BigDecimal individualAgentRate = insureProcessVO.getInsuranceEntity().getIndividualAgentRate();
                    BigDecimal platformAgentRate = insureProcessVO.getInsuranceEntity().getPlatformAgentRate().add(individualAgentRate);
                    warrantyOrderVO.setPlatformFee(
                            warrantyEntity.getPremium().multiply(platformAgentRate)
                                    .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP)
                    );
                }
            } else {
                warrantyOrderVO.setAgentFee(BigDecimal.ZERO);
                warrantyOrderVO.setPlatformFee(BigDecimal.ZERO);
            }
            LocalDateTime now = LocalDateTime.now();
            if (periods != 1) {
                // 计划执行时间
                LocalDateTime scheduleTime;
                if (i != 1) {
                    if (now.getDayOfMonth() <= 10) {
                        scheduleTime = LocalDateTime.of(now.getYear(), now.getMonth(), 5, 0, 0);
                    } else if (now.getDayOfMonth() <= 20) {
                        scheduleTime = LocalDateTime.of(now.getYear(), now.getMonth(), 15, 0, 0);
                    } else {
                        scheduleTime = LocalDateTime.of(now.getYear(), now.getMonth(), 25, 0, 0);
                    }
                    scheduleTime = switch (warrantyEntity.getPeriodicUnit()) {
                        // 按周
                        case InsuranceConstant.WEEK -> LocalDateTimeUtil.offset(scheduleTime, i - 1, ChronoUnit.WEEKS);
                        // 按月
                        case InsuranceConstant.MONTH ->
                                LocalDateTimeUtil.offset(scheduleTime, i - 1, ChronoUnit.MONTHS);
                        // 按年
                        case InsuranceConstant.YEAR -> LocalDateTimeUtil.offset(scheduleTime, i - 1, ChronoUnit.YEARS);
                        default -> throw new RuntimeException("周期单位不符合");
                    };
                } else {
                    scheduleTime = LocalDateTime.now();
                }
                warrantyOrderVO.setScheduleTime(scheduleTime);
            } else {
                warrantyOrderVO.setScheduleTime(now);
            }
            // 宽限期截止时间
            if (StringUtils.isNotBlank(warrantyEntity.getGraceUnit())) {
                LocalDateTime graceTime = switch (warrantyEntity.getGraceUnit()) {
                    case InsuranceConstant.DAY ->
                            LocalDateTimeUtil.offset(warrantyOrderVO.getScheduleTime(), warrantyEntity.getGrace(), ChronoUnit.DAYS);
                    case InsuranceConstant.MONTH ->
                            LocalDateTimeUtil.offset(warrantyOrderVO.getScheduleTime(), warrantyEntity.getGrace(), ChronoUnit.MONTHS);
                    case InsuranceConstant.YEAR ->
                            LocalDateTimeUtil.offset(warrantyOrderVO.getScheduleTime(), warrantyEntity.getGrace(), ChronoUnit.YEARS);
                    default -> throw new RuntimeException("周期单位不符合");
                };
                warrantyOrderVO.setGraceTime(graceTime);
            }
            // 复效期截止时间
            if (StringUtils.isNotBlank(warrantyEntity.getRevivalUnit())) {
                LocalDateTime revivalTime = switch (warrantyEntity.getRevivalUnit()) {
                    // 按天
                    case InsuranceConstant.DAY ->
                            LocalDateTimeUtil.offset(warrantyOrderVO.getScheduleTime(), warrantyEntity.getRevival(), ChronoUnit.DAYS);
                    // 按月
                    case InsuranceConstant.MONTH ->
                            LocalDateTimeUtil.offset(warrantyOrderVO.getScheduleTime(), warrantyEntity.getRevival(), ChronoUnit.MONTHS);
                    // 按年
                    case InsuranceConstant.YEAR ->
                            LocalDateTimeUtil.offset(warrantyOrderVO.getScheduleTime(), warrantyEntity.getRevival(), ChronoUnit.YEARS);
                    default -> throw new RuntimeException("周期单位不符合");
                };
                warrantyOrderVO.setRevivalTime(revivalTime);
            }
            warrantyOrderVO.setApplicantName(warrantyEntity.getApplicantName());
            warrantyOrderVO.setApplicantIdentityCard(warrantyEntity.getApplicantIdentityCard());
            warrantyOrderVOs.add(warrantyOrderVO);
        }
        return warrantyOrderVOs;
    }

    /**
     * 构建保险处理对象
     *
     * @param insuranceId            保险id
     * @param insurancePlanId        保险方案id
     * @param companyNo              保险公司编号
     * @param insuranceCoefficentIds 保障系数项id
     * @return 保险处理对象
     */
    protected final InsuranceProcessDTO buildInsureProcessDTO(Long insuranceId, Long insurancePlanId,
                                                              String companyNo, List<Long> insuranceCoefficentIds) {
        InsuranceEntity insuranceEntity = insuranceService.findInsuranceDetails(insuranceId);
        if (insuranceEntity == null || !EnableEnum.ENABLE.equals(insuranceEntity.getDataState())) {
            throw new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "保险不存在");
        }
        InsurancePlanEntity planEntity = insuranceEntity.getInsurancePlanVOs().stream()
                .filter(plan -> insurancePlanId.equals(plan.getId()) && EnableEnum.ENABLE.equals(plan.getDataState()))
                .findFirst()
                .orElseThrow(() -> new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "保险方案不存在"));
        List<InsuranceCoefficientEntity> coefficientEntities = insuranceEntity.getInsuranceCoefficientVOs().stream()
                .filter(coefficient -> EnableEnum.ENABLE.equals(coefficient.getDataState()) && insuranceCoefficentIds.contains(coefficient.getId()))
                .toList();
        if (CollUtil.isEmpty(coefficientEntities)) {
            throw new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "无保障系数项");
        }
        List<PlanSafeguardEntity> planSafeguardList = planEntity.getPlanSafeguardVOs()
                .stream().filter(planSafeguard -> EnableEnum.ENABLE.equals(planSafeguard.getDataState())).toList();
        if (CollUtil.isEmpty(planSafeguardList)) {
            throw new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "保险方案无保障项");
        }
        ResultDTO<CompanyEntity> resultDTO = companyFeign.findCompanyEntity(companyNo);
        CompanyEntity companyEntity = ResultDTOUtil.assertResultDataNotNull(resultDTO);
        return InsuranceProcessDTO.builder()
                .insuranceEntity(insuranceEntity)
                .insurancePlanEntity(planEntity)
                .companyEntity(companyEntity)
                .planSafeguardList(planSafeguardList)
                .insuranceCoefficientList(coefficientEntities)
                .build();
    }

    /**
     * 构建客户关系列表
     *
     * @param customerRelationIds 客户关系id
     * @return 客户关系列表
     */
    public List<CustomerRelationEntity> buildCustomerRelationList(List<String> customerRelationIds) {
        return customerRelationService.listByIds(customerRelationIds);
    }

    /**
     * 检查保险年龄
     *
     * @param insuranceEntity        保险信息
     * @param customerRelationEntity 客户关系信息
     */
    protected final void checkInsuranceAge(InsuranceEntity insuranceEntity, CustomerRelationEntity customerRelationEntity) {
        // 检查保险年龄
        Long timeStart = insuranceEntity.getTimeStart();
        String timeStartUnit = insuranceEntity.getTimeStartUnit();
        Long timeEnd = insuranceEntity.getTimeEnd();
        String timeEndUnit = insuranceEntity.getTimeEndUnit();
        // 数据缺失, 不做限制
        if (StringUtils.isAnyBlank(timeStartUnit, timeEndUnit) || ObjectUtils.anyNull(timeStart, timeEnd)) {
            return;
        }
        // 根据身份证获取当前年龄, 年龄为0则表示不满一周岁
        long currentAge = IdcardUtil.getAgeByIdCard(customerRelationEntity.getIdentityCard());
        boolean result = true;
        // 年龄小于1岁直接拒绝
        if (InsuranceConstant.YEAR.equals(timeStartUnit) && currentAge == 0L) {
            result = false;
            // 年龄大于1岁则检查时间范围
        } else if (InsuranceConstant.YEAR.equals(timeStartUnit)) {
            result = currentAge >= timeStart && currentAge <= timeEnd;
            // 年龄小于1岁 出生天数是否大于开始时间
        } else if (InsuranceConstant.DAY.equals(timeStartUnit) && currentAge == 0L) {
            DateTime date = IdcardUtil.getBirthDate(customerRelationEntity.getIdentityCard());
            long until = LocalDateTimeUtil.between(date.toLocalDateTime(), LocalDateTime.now(), ChronoUnit.DAYS);
            result = until >= timeStart && until <= timeEnd;
        } else if (InsuranceConstant.DAY.equals(timeStartUnit)) {
            result = timeEnd >= currentAge;
        }

        if (!result) {
            throw new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "年龄不满足要求");
        }
    }

    /**
     * 检查基础系数项是否唯一
     *
     * @param coefficientEntities 保障系数项列表
     */
    protected final void checkBaseOnly(List<InsuranceCoefficientEntity> coefficientEntities) {
        Map<String, List<InsuranceCoefficientEntity>> collect = coefficientEntities.stream()
                .collect(Collectors.groupingBy(InsuranceCoefficientEntity::getCoefficientKey));
        if (collect.values().stream().anyMatch(list -> list.size() > 1)) {
            throw new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "基础系数项重复");
        }
    }

    /**
     * 检查必要系数项
     *
     * @param coefficientEntities 保障系数项列表
     * @param requireCoefficient  必要系数项
     */
    protected final void checkRequireCoefficient(List<InsuranceCoefficientEntity> coefficientEntities, Set<String> requireCoefficient) {
        Set<String> collect = coefficientEntities.stream().map(InsuranceCoefficientEntity::getCoefficientKey).collect(Collectors.toSet());
        if (!CollUtil.containsAll(collect, requireCoefficient)) {
            throw new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "缺少必要系数项");
        }
    }

    /**
     * 购买方式系数项处理
     *
     * @param coefficientEntities 保障系数项列表
     */
    protected final void checkBuyMode(List<InsuranceCoefficientEntity> coefficientEntities) {
        Map<String, InsuranceCoefficientEntity> collect = buildCoefficientMap(coefficientEntities);
        JsonAttributeDTO jsonAttribute = getJsonAttribute(collect, InsuranceConstant.BUY_MODE);
        // 是否为追投方式
        if (InsuranceConstant.BUY_MODE_0.equals(jsonAttribute.getVal()) &&
                (ObjectUtils.anyNull(collect.get(InsuranceConstant.PERIODIC_UNIT), collect.get(InsuranceConstant.PERIODIC)))) {
            throw new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "请选择追投方式");

        }

    }

    protected static Map<String, InsuranceCoefficientEntity> buildCoefficientMap(List<InsuranceCoefficientEntity> coefficientEntities) {
        return coefficientEntities.stream().collect(Collectors.toMap(InsuranceCoefficientEntity::getCoefficientKey, v -> v));
    }

    /**
     * 年龄系数项处理
     *
     * @param insuranceCoefficientList 保障系数项列表
     * @param insuranceId              保险id
     * @param customerRelationEntity   客户关系信息
     */
    protected final void ageHandler(
            List<InsuranceCoefficientEntity> insuranceCoefficientList,
            Long insuranceId, CustomerRelationEntity customerRelationEntity) {
        InsuranceCoefficientEntity findDTO = InsuranceCoefficientEntity.builder()
                .coefficientKey(InsuranceConstant.RANGE_AGE)
                .insuranceId(insuranceId)
                .build();
        List<InsuranceCoefficientEntity> rangeAgeList = insuranceCoefficientService.findList(findDTO);
        if (CollUtil.isEmpty(rangeAgeList)) return;
        String identityCard = customerRelationEntity.getIdentityCard();
        long age = IdcardUtil.getAgeByIdCard(identityCard);
        List<InsuranceCoefficientEntity> rangeAgeListHandler = rangeAgeList.stream().filter(rangeAge -> {
            String coefficientValue = rangeAge.getCoefficientValue();
            RangJsonAttributeDTO attributeDTO = JsonUtil.fromJson(coefficientValue, RangJsonAttributeDTO.class);
            // 保险起始单位：天,且获得年龄等于0，则要进行天数判断
            if (InsuranceConstant.DAY.equals(attributeDTO.getStartUnit()) && age == 0) {
                DateTime birthDate = IdcardUtil.getBirthDate(identityCard);
                long until = LocalDateTimeUtil.between(birthDate.toLocalDateTime(), LocalDateTime.now(), ChronoUnit.DAYS);
                return Long.parseLong(attributeDTO.getStart()) < until;
                // 保险起始单位：年,且获得年龄大于0，则要进行年龄判断
            } else if (InsuranceConstant.YEAR.equals(attributeDTO.getStartUnit()) && age > 0) {
                return Long.parseLong(attributeDTO.getStart()) <= age
                        && Long.parseLong(attributeDTO.getEnd()) > age;
            } else {
                return false;
            }
        }).toList();
        insuranceCoefficientList.addAll(rangeAgeListHandler);
    }

    /**
     * 人数系数项处理
     *
     * @param insuranceCoefficientList 保障系数项列表
     * @param insuranceId              保险id
     * @param customerRelationEntities 客户关系列表
     * @return 处理后的系数项列表
     */
    protected List<InsuranceCoefficientEntity> numberOfPeopleHandler(
            List<InsuranceCoefficientEntity> insuranceCoefficientList, Long insuranceId,
            List<CustomerRelationEntity> customerRelationEntities) {
        // 保险：人数系数
        InsuranceCoefficientEntity insuranceCoefficentVO = InsuranceCoefficientEntity.builder()
                .coefficientKey(InsuranceConstant.NUMBER_OF_PEOPLE)
                .insuranceId(insuranceId)
                .build();
        List<InsuranceCoefficientEntity> numberOfPeopleList = insuranceCoefficientService.findList(insuranceCoefficentVO);
        if (CollUtil.isEmpty(numberOfPeopleList)) return insuranceCoefficientList;
        // 获得投保人数
        long numberOfPeople = customerRelationEntities.size();
        List<InsuranceCoefficientEntity> numberOfPeopleListHandler = numberOfPeopleList.stream().filter(coefficient -> {
            // 转换为RangJsonAttribute处理对象
            String coefficientValue = coefficient.getCoefficientValue();
            RangJsonAttributeDTO rangJsonAttribute = JsonUtil.fromJson(coefficientValue, RangJsonAttributeDTO.class);
            // 投保人所在范围
            return numberOfPeople >= Long.parseLong(rangJsonAttribute.getStart()) &&
                    numberOfPeople < Long.parseLong(rangJsonAttribute.getEnd());
        }).toList();
        // 确定投入人数系数后需要累加
        insuranceCoefficientList.addAll(numberOfPeopleListHandler);
        return insuranceCoefficientList;
    }

    protected final JsonAttributeDTO getJsonAttribute(Map<String, InsuranceCoefficientEntity> coefficientMap, String coefficientKey) {
        InsuranceCoefficientEntity insuranceCoefficientVO = coefficientMap.get(coefficientKey);
        if (insuranceCoefficientVO == null) {
            throw new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "Error Data");
        }
        String coefficientValue = insuranceCoefficientVO.getCoefficientValue();
        return JsonUtil.fromJson(coefficientValue, JsonAttributeDTO.class);
    }

    public CustomerRelationEntity buildApplicant() {
        // 当前登录人
        Long customerId = SubjectContentUtil.getUserVO().getId();
        // 当前登录人关系
        CustomerRelationEntity findDTO = CustomerRelationEntity.builder()
                .customerId(customerId)
                .dataState(EnableEnum.ENABLE)
                .build();
        List<CustomerRelationEntity> list = customerRelationService.findRelationList(findDTO);
        // 投保人
        return list.stream()
                .filter(n -> CustomerRelationEnum.SELF.getCode().equals(n.getRelation()))
                .findFirst().orElseThrow(() -> new AppException(ResponseCode.INSURANCE_CALCULATE_ERROR, "请先维护个人信息"));
    }

    /**
     * 时间处理
     *
     * @param doInsureVo  投保信息
     * @param collect     系数项
     * @param insuranceVO 保险信息
     */
    protected WarrantyTimeDTO buildTimeSetup(DoInsuranceDTO doInsureVo, Map<String, InsuranceCoefficientEntity> collect,
                                             InsuranceEntity insuranceVO) {
        // 保障起始时间
        LocalDateTime safeguardStartTime = ObjectUtils.defaultIfNull(doInsureVo.getSafeguardStartTime(), LocalDateTime.now());
        // 犹豫期截止时间
        LocalDateTime hesitationTime = null;
        // 等待期截止时间
        LocalDateTime waitTime = null;
        // 保障截止时间
        LocalDateTime safeguardEndTime = null;
        // 医疗和重疾类保险才有等待期
        if (doInsureVo.getCheckRule().equals(CheckRuleEnum.MEDICAL.getCode()) ||
                doInsureVo.getCheckRule().equals(CheckRuleEnum.CRITICAL.getCode())) {
            waitTime = LocalDateTimeUtil.offset(LocalDateTime.now(), insuranceVO.getWaits(), ChronoUnit.DAYS);
        }
        // 医疗、重疾类、养老、储蓄保险才有犹豫期期
        if (doInsureVo.getCheckRule().equals(CheckRuleEnum.MEDICAL.getCode()) ||
                doInsureVo.getCheckRule().equals(CheckRuleEnum.CRITICAL.getCode()) ||
                doInsureVo.getCheckRule().equals(CheckRuleEnum.ELDERLY.getCode()) ||
                doInsureVo.getCheckRule().equals(CheckRuleEnum.SAVING.getCode())) {
            hesitationTime = LocalDateTimeUtil.offset(LocalDateTime.now(), insuranceVO.getHesitation(), ChronoUnit.DAYS);
        }
        // 养老和储蓄类保险无保障结束时间
        if (!doInsureVo.getCheckRule().equals(CheckRuleEnum.ELDERLY.getCode()) &&
                !doInsureVo.getCheckRule().equals(CheckRuleEnum.SAVING.getCode())) {
            // 保障期限
            JsonAttributeDTO protectionPeriodJsonAttribute = getJsonAttribute(collect, InsuranceConstant.PROTECTION_PERIOD);
            String valProtectionPeriod = protectionPeriodJsonAttribute.getUnit();
            String calculatedVal = protectionPeriodJsonAttribute.getCalculatedVal();
            int rearwardShift;
            // 推迟：年计算
            if (valProtectionPeriod.equals(InsuranceConstant.YEAR)) {
                rearwardShift = Integer.parseInt(calculatedVal);
                safeguardEndTime = LocalDateTimeUtil.offset(safeguardStartTime, rearwardShift, ChronoUnit.YEARS);
            }
            // 推迟：月计算
            if (valProtectionPeriod.equals(InsuranceConstant.MONTH)) {
                rearwardShift = Integer.parseInt(calculatedVal);
                safeguardEndTime = LocalDateTimeUtil.offset(safeguardStartTime, rearwardShift, ChronoUnit.MONTHS);
            }
            // 推迟：天计算
            if (valProtectionPeriod.equals(InsuranceConstant.DAY)) {
                rearwardShift = Integer.parseInt(calculatedVal);
                safeguardEndTime = LocalDateTimeUtil.offset(safeguardStartTime, rearwardShift, ChronoUnit.DAYS);
            }
        }
        return WarrantyTimeDTO.builder()
                .hesitationTime(hesitationTime)
                .waitTime(waitTime)
                .safeguardStartTime(safeguardStartTime)
                .safeguardEndTime(safeguardEndTime).build();
    }

    /**
     * 周期时长计算
     *
     * @param collect 系数
     */
    protected Integer doPeriods(Map<String, InsuranceCoefficientEntity> collect) {
        // 投入周期时长【投3年、投5年、投10年】
        BigDecimal periodic = new BigDecimal(getJsonAttribute(collect, InsuranceConstant.PERIODIC).getCalculatedVal());
        // 投入周期单位
        String periodicUnit = getJsonAttribute(collect, InsuranceConstant.PERIODIC_UNIT).getVal();
        // 周期计算
        periodic = switch (periodicUnit) {
            // 按周
            case InsuranceConstant.WEEK -> periodic.multiply(new BigDecimal(52));
            // 按月
            case InsuranceConstant.MONTH -> periodic.multiply(new BigDecimal(12));
            // 按年
            case InsuranceConstant.YEAR -> periodic.multiply(new BigDecimal(1));
            default -> throw new RuntimeException("周期单位不符合");
        };
        return periodic.intValue();
    }

}
